package Franction;

public class Matrix {
    Franction[][] elements;
    int n;
    int m;

    public static void main(String[] args) {
        Matrix b_1 = new Matrix(3, 3, "0.50    -0.25   0.00 0.00    0.50    0.00 -2.00   1.00    1.00");
        Matrix b_ = new Matrix(3, 1, "430,480,400");
        System.out.println(b_1.dot(b_));
        int stop = 1;
    }

    public Matrix(int i, int j) {
        n = i;
        m = j;
        elements = new Franction[n][m];
    }

    public Matrix(int i, int j, String Str) {
        this(i, j);
        SetArray(Str);
    }

    public static Matrix IMatrix(int n) {
        Matrix m = new Matrix(n, n);
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++) {
                if (i == j)
                    m.elements[i][j] = new Franction(1, 1);
                else
                    m.elements[i][j] = new Franction("0");
            }
        return m;
    }

    public Matrix connect(Matrix t) {
        Matrix tmp = new Matrix(n, m + t.m);
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                tmp.elements[i][j] = new Franction(elements[i][j]);
        for (int i = 0; i < n; i++)
            for (int j = m; j < tmp.m; j++)
                tmp.elements[i][j] = new Franction(t.elements[i][j - m]);
        return tmp;
    }

    public void SetArray(Franction[] f) {
        for (int i = 0, j = 0; i < f.length; i++, j++)
            elements[j / m][j % m] = new Franction(f[i]);
    }

    public void SetArray(String str) {
        SetArray(Franction.toList(str));
    }

    public void rotate(int i, int j) {
        for (int a = 0; a < n; a++) {
            if (a == i - 1)
                continue;
            Franction tmp = new Franction(elements[a][j - 1].divide(elements[i - 1][j - 1]));
            for (int b = 0; b < m; b++) {
                elements[a][b].Copy(elements[a][b].minus(elements[i - 1][b].multiply(tmp)));
            }
        }
        Franction tmp = new Franction(elements[i - 1][j - 1]);
        for (int b = 0; b < m; b++)
            elements[i - 1][b].Copy(elements[i - 1][b].divide(tmp));
    }

    public Matrix inverse() {
        if (n != m)
            return IMatrix(0);
        Matrix t = connect(IMatrix(n));
        for (int i = 0; i < n; i++)
            t.rotate(i + 1, i + 1);
        Matrix t1 = new Matrix(n, n);
        for (int i = 0; i < n; i++)
            for (int j = 0; j < n; j++)
                t1.elements[i][j] = new Franction(t.elements[i][j + n]);
        return t1;
    }

    public Matrix addMatrix(Matrix t) {
        if (n < t.n || m < t.m)
            return IMatrix(0);
        Matrix tmp = new Matrix(n, m);
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                tmp.elements[i][j] = new Franction(elements[i][j].add(t.elements[i][j]));
        return tmp;
    }

    public Matrix minusMatrix(Matrix t) {
        if (n < t.n || m < t.m)
            return IMatrix(0);
        Matrix tmp = new Matrix(n, m);
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                tmp.elements[i][j] = new Franction(elements[i][j].minus(t.elements[i][j]));
        return tmp;
    }

    public Matrix dot(Matrix t) {
        if (m != t.n)
            return IMatrix(0);
        Matrix tmp = new Matrix(n, t.m);
        for (int i = 0; i < tmp.n; i++)
            for (int j = 0; j < tmp.m; j++) {
                Franction f = new Franction();
                for (int k = 0; k < m; k++)
                    f.Copy(f.add(elements[i][k].multiply(t.elements[k][j])));
                tmp.elements[i][j] = new Franction(f);
            }
        return tmp;
    }

    public Matrix tranc() {
        Matrix t = new Matrix(m, n);
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++)
                t.elements[j][i] = new Franction(elements[i][j]);
        return t;
    }

    public String toString() {
        String str = "";
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                str += "\t" + elements[i][j].toStrIO();
            }
            str += "\n";
        }
        return str;
    }

    public String toStrIO() {
        String str = "";
        for (int i = 0; i < n; i++)
            for (int j = 0; j < m; j++) {
                str += elements[i][j].toStrIO() + ",";
            }
        return str;
    }
}
